Setup
Ensure that the development version of DiagrammeR is installed. Load in the package with library().
#devtools::install_github("rich-iannone/DiagrammeR")
library(DiagrammeR)
Part 1. Information on All Nodes and Edges
When you have a graph object, sometimes you’ll want to poke around and inspect some of the nodes, and some of the edges. There are very good reasons for doing so. There can be valuable information within the nodes and edges. Further graph construction may hinge on what’s extant in the graph. Also, inspection is a good way to verify that a graph modification has indeed taken place in the correct manner.
First, let’s build a graph to use for the examples. For the node data frame we will include values for the type, label, and data attributes. The edge data frame will contain the rel, color, and weight edge attributes.
# Create a node data frame (ndf) with
# 4 nodes
ndf <-
create_node_df(
n = 4,
type = "number",
label = c("one", "two",
"three", "four"),
data = c(3.5, 2.6, 9.4, 2.7))
# Create an edge data frame (ndf) with
# 4 edges
edf <-
create_edge_df(
from = c(1, 2, 3, 4),
to = c(4, 3, 1, 1),
rel = c("P", "B", "L", "L"),
color = c("green", "blue", "red", "red"),
weight = c(2.1, 5.7, 10.1, 3.9))
graph <-
create_graph(
nodes_df = ndf,
edges_df = edf)
# Render the graph to see it in the RStudio Viewer
render_graph(graph)
The get_node_ids() function simply returns a vector of node ID values. This is useful in many cases and is great when used as a sanity check.
get_node_ids(graph)
[1] 1 2 3 4
Using the node_info() function provides a data frame with detailed information on nodes and their interrelationships within a graph. It always returns the same columns, in the same order. It returns as many rows as there are nodes in the graph. It’s useful when you want a quick summary of the node ID values, their labels and type values, and their degrees of connectness with other nodes.
node_info(graph)
In the above table the base attributes of the nodes are provided first (id, type, and label) and then columns with degree information comes next (deg, indeg, and outdeg). The node degree (deg) describes the number of edges to or from the node. The indegree and outdegree divide total degree amount by the number of edges inward to the node and outward from the node, respectively. Finally, the loops column provides the number of self edges for the node (this is an edge that starts and terminates at the same node, so the degree for that is 2).
The get_edges() function returns all of the node ID values related to each edge in the graph:
get_edges(graph)
[1] "1->4" "2->3" "3->1" "4->1"
Like nodes, edges also have ID values. This is important for distinguishability of a pair of nodes has multiple edges between them (and especially if they are in the same direction in a directed graph). To get all edge ID values in the graph, use the get_edge_ids() function.
get_edge_ids(graph)
[1] 1 2 3 4
The edge_info(), like the node_info() function, always returns a data frame with a set number of columns. In this case, it is the edge ID value id, the node ID values from and to that define the links, and, the relationship (rel) labels for the edges.
edge_info(graph)
Part 2. Inspecting Nodes, Edges, and their Attributes
Two of a graph object’s main components are its node data frame (ndf) and its edge data frame (edf). These can be obtained as individual data frames using the get_node_df() and get_edge_df() functions:
# Get the graph's ndf with the `get_node_df()` function
get_node_df(graph)
# Get the graph's edf with the `get_edge_df()` function
get_edge_df(graph)
For the ndf, the id, type, and label columns will always present and in that prescribed order. For the edf, it is the id, from, to, and rel columns will always be present. Any additional columns can be either parameters recognized by the graph rendering engine (e.g., color, fontname, etc.) or non-aesthetic properties of the nodes or edges (e.g., a node data value or an edge weight).
Part 3. Determining Existence of Nodes or Edges
There may be cases where you need to verify that a certain node ID exists in the graph or that an edge definition is present. The node_present() and edge_present() functions will provide a TRUE or FALSE value as confirmation.
Get the node ID values present in the graph with the get_node_ids() function.
get_node_ids(graph)
[1] 1 2 3 4
Is node with ID 1 in the graph? Use node_present() to find out.
node_present(graph, 1)
[1] TRUE
Is node with ID 5 in the graph?
node_present(graph, 5)
[1] FALSE
Get the node ID values associated with the edges present in the graph (with the get_edges() function).
get_edges(graph)
[1] "1->4" "2->3" "3->1" "4->1"
To determine whether an edge is present, the edge_present() function takes 2 arguments after graph: from and to. So, to find out whether the edge 1->4 is present, the following can be used:
edge_present(graph, 1, 4)
[1] TRUE
Since the the edge 2->4 does not exist, the following will return FALSE:
edge_present(graph, 2, 4)
[1] FALSE
LS0tCnRpdGxlOiAiMDA1IC0gSW5zcGVjdGluZyBOb2RlcyBhbmQgRWRnZXMiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCiMjIFNldHVwCgpFbnN1cmUgdGhhdCB0aGUgZGV2ZWxvcG1lbnQgdmVyc2lvbiBvZiAqKkRpYWdyYW1tZVIqKiBpcyBpbnN0YWxsZWQuIExvYWQgaW4gdGhlIHBhY2thZ2Ugd2l0aCBgbGlicmFyeSgpYC4KCmBgYHtyIGxvYWRfcGFja2FnZXMsIHJlc3VsdHM9RkFMU0V9CiNkZXZ0b29sczo6aW5zdGFsbF9naXRodWIoInJpY2gtaWFubm9uZS9EaWFncmFtbWVSIikKCmxpYnJhcnkoRGlhZ3JhbW1lUikKYGBgCgojIyBQYXJ0IDEuIEluZm9ybWF0aW9uIG9uIEFsbCBOb2RlcyBhbmQgRWRnZXMKCldoZW4geW91IGhhdmUgYSBncmFwaCBvYmplY3QsIHNvbWV0aW1lcyB5b3UnbGwgd2FudCB0byBwb2tlIGFyb3VuZCBhbmQgaW5zcGVjdCBzb21lIG9mIHRoZSBub2RlcywgYW5kIHNvbWUgb2YgdGhlIGVkZ2VzLiBUaGVyZSBhcmUgdmVyeSBnb29kIHJlYXNvbnMgZm9yIGRvaW5nIHNvLiBUaGVyZSBjYW4gYmUgdmFsdWFibGUgaW5mb3JtYXRpb24gd2l0aGluIHRoZSBub2RlcyBhbmQgZWRnZXMuIEZ1cnRoZXIgZ3JhcGggY29uc3RydWN0aW9uIG1heSBoaW5nZSBvbiB3aGF0J3MgZXh0YW50IGluIHRoZSBncmFwaC4gQWxzbywgaW5zcGVjdGlvbiBpcyBhIGdvb2Qgd2F5IHRvIHZlcmlmeSB0aGF0IGEgZ3JhcGggbW9kaWZpY2F0aW9uIGhhcyBpbmRlZWQgdGFrZW4gcGxhY2UgaW4gdGhlIGNvcnJlY3QgbWFubmVyLgoKRmlyc3QsIGxldCdzIGJ1aWxkIGEgZ3JhcGggdG8gdXNlIGZvciB0aGUgZXhhbXBsZXMuIEZvciB0aGUgbm9kZSBkYXRhIGZyYW1lIHdlIHdpbGwgaW5jbHVkZSB2YWx1ZXMgZm9yIHRoZSBgdHlwZWAsIGBsYWJlbGAsIGFuZCBgZGF0YWAgYXR0cmlidXRlcy4gVGhlIGVkZ2UgZGF0YSBmcmFtZSB3aWxsIGNvbnRhaW4gdGhlIGByZWxgLCBgY29sb3JgLCBhbmQgYHdlaWdodGAgZWRnZSBhdHRyaWJ1dGVzLgoKYGBge3IgY3JlYXRlX2luaXRpYWxfZ3JhcGh9CiMgQ3JlYXRlIGEgbm9kZSBkYXRhIGZyYW1lIChuZGYpIHdpdGgKIyA0IG5vZGVzCm5kZiA8LQogIGNyZWF0ZV9ub2RlX2RmKAogICAgbiA9IDQsCiAgICB0eXBlID0gIm51bWJlciIsCiAgICBsYWJlbCA9IGMoIm9uZSIsICJ0d28iLAogICAgICAgICAgICAgICJ0aHJlZSIsICJmb3VyIiksCiAgICBkYXRhID0gYygzLjUsIDIuNiwgOS40LCAyLjcpKQoKIyBDcmVhdGUgYW4gZWRnZSBkYXRhIGZyYW1lIChuZGYpIHdpdGgKIyA0IGVkZ2VzCmVkZiA8LQogIGNyZWF0ZV9lZGdlX2RmKAogICAgZnJvbSA9IGMoMSwgMiwgMywgNCksCiAgICB0byA9IGMoNCwgMywgMSwgMSksCiAgICByZWwgPSBjKCJQIiwgIkIiLCAiTCIsICJMIiksCiAgICBjb2xvciA9IGMoImdyZWVuIiwgImJsdWUiLCAicmVkIiwgInJlZCIpLAogICAgd2VpZ2h0ID0gYygyLjEsIDUuNywgMTAuMSwgMy45KSkKCmdyYXBoIDwtCiAgY3JlYXRlX2dyYXBoKAogICAgbm9kZXNfZGYgPSBuZGYsCiAgICBlZGdlc19kZiA9IGVkZikKCiMgUmVuZGVyIHRoZSBncmFwaCB0byBzZWUgaXQgaW4gdGhlIFJTdHVkaW8gVmlld2VyCnJlbmRlcl9ncmFwaChncmFwaCkKYGBgCgpUaGUgYGdldF9ub2RlX2lkcygpYCBmdW5jdGlvbiBzaW1wbHkgcmV0dXJucyBhIHZlY3RvciBvZiBub2RlIElEIHZhbHVlcy4gVGhpcyBpcyB1c2VmdWwgaW4gbWFueSBjYXNlcyBhbmQgaXMgZ3JlYXQgd2hlbiB1c2VkIGFzIGEgc2FuaXR5IGNoZWNrLgoKYGBge3IgdXNlX2dldF9ub2RlX2lkc30KZ2V0X25vZGVfaWRzKGdyYXBoKQpgYGAKClVzaW5nIHRoZSBgbm9kZV9pbmZvKClgIGZ1bmN0aW9uIHByb3ZpZGVzIGEgZGF0YSBmcmFtZSB3aXRoIGRldGFpbGVkIGluZm9ybWF0aW9uIG9uIG5vZGVzIGFuZCB0aGVpciBpbnRlcnJlbGF0aW9uc2hpcHMgd2l0aGluIGEgZ3JhcGguIEl0IGFsd2F5cyByZXR1cm5zIHRoZSBzYW1lIGNvbHVtbnMsIGluIHRoZSBzYW1lIG9yZGVyLiBJdCByZXR1cm5zIGFzIG1hbnkgcm93cyBhcyB0aGVyZSBhcmUgbm9kZXMgaW4gdGhlIGdyYXBoLiBJdCdzIHVzZWZ1bCB3aGVuIHlvdSB3YW50IGEgcXVpY2sgc3VtbWFyeSBvZiB0aGUgbm9kZSBJRCB2YWx1ZXMsIHRoZWlyIGxhYmVscyBhbmQgYHR5cGVgIHZhbHVlcywgYW5kIHRoZWlyIGRlZ3JlZXMgb2YgY29ubmVjdG5lc3Mgd2l0aCBvdGhlciBub2Rlcy4KCmBgYHtyIHVzZV9ub2RlX2luZm99Cm5vZGVfaW5mbyhncmFwaCkKYGBgCgpJbiB0aGUgYWJvdmUgdGFibGUgdGhlIGJhc2UgYXR0cmlidXRlcyBvZiB0aGUgbm9kZXMgYXJlIHByb3ZpZGVkIGZpcnN0IChgaWRgLCBgdHlwZWAsIGFuZCBgbGFiZWxgKSBhbmQgdGhlbiBjb2x1bW5zIHdpdGggZGVncmVlIGluZm9ybWF0aW9uIGNvbWVzIG5leHQgKGBkZWdgLCBgaW5kZWdgLCBhbmQgYG91dGRlZ2ApLiBUaGUgbm9kZSBkZWdyZWUgKGBkZWdgKSBkZXNjcmliZXMgdGhlIG51bWJlciBvZiBlZGdlcyB0byBvciBmcm9tIHRoZSBub2RlLiBUaGUgaW5kZWdyZWUgYW5kIG91dGRlZ3JlZSBkaXZpZGUgdG90YWwgZGVncmVlIGFtb3VudCBieSB0aGUgbnVtYmVyIG9mIGVkZ2VzIGlud2FyZCB0byB0aGUgbm9kZSBhbmQgb3V0d2FyZCBmcm9tIHRoZSBub2RlLCByZXNwZWN0aXZlbHkuIEZpbmFsbHksIHRoZSBgbG9vcHNgIGNvbHVtbiBwcm92aWRlcyB0aGUgbnVtYmVyIG9mIHNlbGYgZWRnZXMgZm9yIHRoZSBub2RlICh0aGlzIGlzIGFuIGVkZ2UgdGhhdCBzdGFydHMgYW5kIHRlcm1pbmF0ZXMgYXQgdGhlIHNhbWUgbm9kZSwgc28gdGhlIGRlZ3JlZSBmb3IgdGhhdCBpcyAyKS4KClRoZSBgZ2V0X2VkZ2VzKClgIGZ1bmN0aW9uIHJldHVybnMgYWxsIG9mIHRoZSBub2RlIElEIHZhbHVlcyByZWxhdGVkIHRvIGVhY2ggZWRnZSBpbiB0aGUgZ3JhcGg6CgpgYGB7ciB1c2VfZ2V0X2VkZ2VzfQpnZXRfZWRnZXMoZ3JhcGgpCmBgYAoKTGlrZSBub2RlcywgZWRnZXMgYWxzbyBoYXZlIElEIHZhbHVlcy4gVGhpcyBpcyBpbXBvcnRhbnQgZm9yIGRpc3Rpbmd1aXNoYWJpbGl0eSBvZiBhIHBhaXIgb2Ygbm9kZXMgaGFzIG11bHRpcGxlIGVkZ2VzIGJldHdlZW4gdGhlbSAoYW5kIGVzcGVjaWFsbHkgaWYgdGhleSBhcmUgaW4gdGhlIHNhbWUgZGlyZWN0aW9uIGluIGEgZGlyZWN0ZWQgZ3JhcGgpLiBUbyBnZXQgYWxsIGVkZ2UgSUQgdmFsdWVzIGluIHRoZSBncmFwaCwgdXNlIHRoZSBgZ2V0X2VkZ2VfaWRzKClgIGZ1bmN0aW9uLgoKYGBge3IgdXNlX2dldF9lZGdlX2lkc30KZ2V0X2VkZ2VfaWRzKGdyYXBoKQpgYGAKClRoZSBgZWRnZV9pbmZvKClgLCBsaWtlIHRoZSBgbm9kZV9pbmZvKClgIGZ1bmN0aW9uLCBhbHdheXMgcmV0dXJucyBhIGRhdGEgZnJhbWUgd2l0aCBhIHNldCBudW1iZXIgb2YgY29sdW1ucy4gSW4gdGhpcyBjYXNlLCBpdCBpcyB0aGUgZWRnZSBJRCB2YWx1ZSBgaWRgLCB0aGUgbm9kZSBJRCB2YWx1ZXMgYGZyb21gIGFuZCBgdG9gIHRoYXQgZGVmaW5lIHRoZSBsaW5rcywgYW5kLCB0aGUgcmVsYXRpb25zaGlwIChgcmVsYCkgbGFiZWxzIGZvciB0aGUgZWRnZXMuCgpgYGB7ciB1c2VfZWRnZV9pbmZvfQplZGdlX2luZm8oZ3JhcGgpCmBgYAoKIyMgUGFydCAyLiBJbnNwZWN0aW5nIE5vZGVzLCBFZGdlcywgYW5kIHRoZWlyIEF0dHJpYnV0ZXMKClR3byBvZiBhIGdyYXBoIG9iamVjdCdzIG1haW4gY29tcG9uZW50cyBhcmUgaXRzIG5vZGUgZGF0YSBmcmFtZSAobmRmKSBhbmQgaXRzIGVkZ2UgZGF0YSBmcmFtZSAoZWRmKS4gVGhlc2UgY2FuIGJlIG9idGFpbmVkIGFzIGluZGl2aWR1YWwgZGF0YSBmcmFtZXMgdXNpbmcgdGhlIGBnZXRfbm9kZV9kZigpYCBhbmQgYGdldF9lZGdlX2RmKClgIGZ1bmN0aW9uczoKCmBgYHtyIHVzZV9nZXRfbm9kZV9kZn0KIyBHZXQgdGhlIGdyYXBoJ3MgbmRmIHdpdGggdGhlIGBnZXRfbm9kZV9kZigpYCBmdW5jdGlvbgpnZXRfbm9kZV9kZihncmFwaCkKYGBgCgpgYGB7ciB1c2VfZ2V0X2VkZ2VfZGZ9CiMgR2V0IHRoZSBncmFwaCdzIGVkZiB3aXRoIHRoZSBgZ2V0X2VkZ2VfZGYoKWAgZnVuY3Rpb24KZ2V0X2VkZ2VfZGYoZ3JhcGgpCmBgYAoKRm9yIHRoZSBuZGYsIHRoZSBgaWRgLCBgdHlwZWAsIGFuZCBgbGFiZWxgIGNvbHVtbnMgd2lsbCBhbHdheXMgcHJlc2VudCBhbmQgaW4gdGhhdCBwcmVzY3JpYmVkIG9yZGVyLiBGb3IgdGhlIGVkZiwgaXQgaXMgdGhlIGBpZGAsIGBmcm9tYCwgYHRvYCwgYW5kIGByZWxgIGNvbHVtbnMgd2lsbCBhbHdheXMgYmUgcHJlc2VudC4gQW55IGFkZGl0aW9uYWwgY29sdW1ucyBjYW4gYmUgZWl0aGVyIHBhcmFtZXRlcnMgcmVjb2duaXplZCBieSB0aGUgZ3JhcGggcmVuZGVyaW5nIGVuZ2luZSAoZS5nLiwgYGNvbG9yYCwgYGZvbnRuYW1lYCwgZXRjLikgb3Igbm9uLWFlc3RoZXRpYyBwcm9wZXJ0aWVzIG9mIHRoZSBub2RlcyBvciBlZGdlcyAoZS5nLiwgYSBub2RlIGBkYXRhYCB2YWx1ZSBvciBhbiBlZGdlIGB3ZWlnaHRgKS4KCiMjIFBhcnQgMy4gRGV0ZXJtaW5pbmcgRXhpc3RlbmNlIG9mIE5vZGVzIG9yIEVkZ2VzCgpUaGVyZSBtYXkgYmUgY2FzZXMgd2hlcmUgeW91IG5lZWQgdG8gdmVyaWZ5IHRoYXQgYSBjZXJ0YWluIG5vZGUgSUQgZXhpc3RzIGluIHRoZSBncmFwaCBvciB0aGF0IGFuIGVkZ2UgZGVmaW5pdGlvbiBpcyBwcmVzZW50LiBUaGUgYG5vZGVfcHJlc2VudCgpYCBhbmQgYGVkZ2VfcHJlc2VudCgpYCBmdW5jdGlvbnMgd2lsbCBwcm92aWRlIGEgYFRSVUVgIG9yIGBGQUxTRWAgdmFsdWUgYXMgY29uZmlybWF0aW9uLgoKR2V0IHRoZSBub2RlIElEIHZhbHVlcyBwcmVzZW50IGluIHRoZSBncmFwaCB3aXRoIHRoZSBgZ2V0X25vZGVfaWRzKClgIGZ1bmN0aW9uLgoKYGBge3IgdXNlX2dldF9ub2RlX2lkXzJ9CmdldF9ub2RlX2lkcyhncmFwaCkKYGBgCgpJcyBub2RlIHdpdGggSUQgYDFgIGluIHRoZSBncmFwaD8gVXNlIGBub2RlX3ByZXNlbnQoKWAgdG8gZmluZCBvdXQuCgpgYGB7ciBpc19ub2RlXzFfcHJlc2VudH0Kbm9kZV9wcmVzZW50KGdyYXBoLCAxKQpgYGAKCklzIG5vZGUgd2l0aCBJRCBgNWAgaW4gdGhlIGdyYXBoPwoKYGBge3IgaXNfbm9kZV81X3ByZXNlbnR9Cm5vZGVfcHJlc2VudChncmFwaCwgNSkKYGBgCgpHZXQgdGhlIG5vZGUgSUQgdmFsdWVzIGFzc29jaWF0ZWQgd2l0aCB0aGUgZWRnZXMgcHJlc2VudCBpbiB0aGUgZ3JhcGggKHdpdGggdGhlIGBnZXRfZWRnZXMoKWAgZnVuY3Rpb24pLgoKYGBge3IgdXNlX2dldF9lZGdlc18yfQpnZXRfZWRnZXMoZ3JhcGgpCmBgYAoKVG8gZGV0ZXJtaW5lIHdoZXRoZXIgYW4gZWRnZSBpcyBwcmVzZW50LCB0aGUgYGVkZ2VfcHJlc2VudCgpYCBmdW5jdGlvbiB0YWtlcyAyIGFyZ3VtZW50cyBhZnRlciBgZ3JhcGhgOiBgZnJvbWAgYW5kIGB0b2AuIFNvLCB0byBmaW5kIG91dCB3aGV0aGVyIHRoZSBlZGdlIGAxLT40YCBpcyBwcmVzZW50LCB0aGUgZm9sbG93aW5nIGNhbiBiZSB1c2VkOgoKYGBge3IgaXNfZWRnZV8xXzRfcHJlc2VudH0KZWRnZV9wcmVzZW50KGdyYXBoLCAxLCA0KQpgYGAKClNpbmNlIHRoZSB0aGUgZWRnZSBgMi0+NGAgZG9lcyBub3QgZXhpc3QsIHRoZSBmb2xsb3dpbmcgd2lsbCByZXR1cm4gRkFMU0U6CgpgYGB7ciBpc19lZGdlXzJfNF9wcmVzZW50fQplZGdlX3ByZXNlbnQoZ3JhcGgsIDIsIDQpCmBgYAoK